package main

import (
	"bufio"
	"fmt"
	"log"
	"net"
	"time"
)

var localPort1 = 51660
var localPort2 = 51661

type UDP struct {
	ip         string
	port       int
	ips        []string
	remoteName string
	remotePort int
}

func NewUDP(ipaddr []string, port int) *UDP {
	return &UDP{
		ip:         ipaddr[0],
		ips:        ipaddr,
		port:       port,
		remoteName: "",
		remotePort: 0,
	}
}
func (udp *UDP) NewServer() {
	addr := net.UDPAddr{Port: udp.port, IP: net.ParseIP(udp.ip)}
	fmt.Println(addr)
	conn, err := net.ListenUDP("udp", &addr)
	if err != nil {
		log.Fatal(err)
	}
	b := make([]byte, 2048)
	for {
		fmt.Printf("Accepting a new packet\n")
		cc, remote, rderr := conn.ReadFromUDP(b)
		if rderr != nil {
			fmt.Printf("net.ReadFromUDP() error: %s\n", rderr)
		}

		fmt.Printf("Remote address: %v\n", remote)
		udp.remoteName = remote.IP.String()
		udp.remotePort = remote.Port
		// cc, wrerr := conn.WriteTo(b[0:cc], remote)
		result := fmt.Sprintf("%s:%d", remote.IP, remote.Port)
		cc, wrerr := conn.WriteTo([]byte(result), remote)
		if wrerr != nil {
			fmt.Printf("net.WriteTo() error: %s\n", wrerr)
		} else {
			fmt.Printf("Wrote %d bytes to socket\n", cc)
		}
		go udp.sendAndWait()
	}

}
func (udp *UDP) SendAndWait() {
	for _ = range time.Tick(2 * time.Second) {
		udp.sendAndWait()
	}
}
func (udp *UDP) sendAndWait() {
	var laddr *net.UDPAddr

	if len(udp.ips) > 1 {
		laddr, _ = net.ResolveUDPAddr("udp", fmt.Sprintf("%s:%d", udp.ips[1], localPort1))
	} else {
		laddr, _ = net.ResolveUDPAddr("udp", fmt.Sprintf("%s:%d", udp.ip, localPort1))
	}
	fmt.Println("SendWait Addr", laddr)
	service := fmt.Sprintf("%s:%d", udp.remoteName, udp.remotePort)
	RemoteAddr, err := net.ResolveUDPAddr("udp", service)
	p := make([]byte, 2048)
	conn, err := net.DialUDP("udp", laddr, RemoteAddr)
	if err != nil {
		fmt.Printf("Some error %v", err)
		return
	}
	defer conn.Close()
	fmt.Fprintf(conn, "0123456789")
	w := time.Now().Add(time.Duration(1 * 1e9))
	conn.SetReadDeadline(w)
	_, err = bufio.NewReader(conn).Read(p)
	if err == nil {
		fmt.Printf("%s\n", p)
	} else {
		fmt.Printf("Some error %v\n", err)
	}

}
